package org.pf.base.pfGraphics
{
	import flash.display.*;
	import flash.events.Event;
	import flash.geom.*;
	import org.pf.semaphore.events.PFCommonSemaphoreEvent;
	
	/**
	 * ...
	 * @author Raymond de la Croix
	 */
	public class PFTileAnimation extends Sprite
	{
		public var animationSheet:Bitmap;
		
		private var tileWidth:int;
		private var tileHeight:int;
		private var xTilesLength:int;
		private var yTilesLength:int;
		public var animationXIndex:int = 0;
		public var animationYIndex:int = 0;
		private var animationCount:int = 0;
		public var animationDelay:int;
		
		private var canvasBD:BitmapData;
		private var canvasBitmap:Bitmap;
		private var tileSheet:BitmapData;
		private var tileRect:Rectangle;
		private var tilePoint:Point;
		
		public var endOfAnimation:Boolean = false;
		public var lastLoop:Boolean = false;
		private var flipped:Boolean = true;
		public var triggered:Boolean = false;
		
		public function PFTileAnimation(tileWidth:int, tileHeight:int, xTilesLength:int, yTilesLength:int, animationSheet:Bitmap, animationDelay:int)
		{
			this.tileWidth = tileWidth;
			this.tileHeight = tileHeight;
			this.xTilesLength = xTilesLength;
			this.yTilesLength = yTilesLength;
			animationXIndex = 0;
			animationYIndex = 0;
			animationCount = 0;
			this.animationDelay = animationDelay;
			
			canvasBD = new BitmapData(tileWidth, tileHeight);
			canvasBitmap = new Bitmap(canvasBD);
			this.animationSheet = animationSheet;
			tileSheet = new BitmapData(tileWidth, tileHeight);
			tileSheet = animationSheet.bitmapData;
			
			tileRect = new Rectangle(0, 0, tileWidth, tileHeight);
			tilePoint = new Point(0, 0);
			
			canvasBitmap.cacheAsBitmap = true;
			addChild(canvasBitmap);
			addEventListener(Event.ENTER_FRAME, onEnterframe);
		}
		
		public function triggerEvent(animationXIndex:int, animationYIndex:int):Boolean
		{
			var returnState:Boolean = false;
			if (this.animationXIndex == animationXIndex && this.animationYIndex == animationYIndex && triggered == false)
			{
				triggered = true;
				returnState = true;
			}
			if (this.animationXIndex != animationXIndex && this.animationYIndex != animationYIndex)
			{
				triggered = false;
				returnState = false
			}
			return returnState;
		}
		
		public function changeSheet(tileWidth:int, tileHeight:int, xTilesLength:int, yTilesLength:int, animationSheet:Bitmap, animationDelay:int, mirrorX:Boolean = false):Boolean
		{
			this.animationYIndex = 0;
			this.animationXIndex = 0;
			this.tileSheet = animationSheet.bitmapData;
			this.animationDelay = animationDelay;
			this.tileWidth = tileWidth;
			this.tileHeight = tileHeight;
			this.xTilesLength = xTilesLength;
			this.yTilesLength = yTilesLength;
			if (mirrorX == true)
			{
				this.canvasBitmap.scaleX *= -1;
				if (this.flipped == true)
				{
					this.flipped = false;
					this.canvasBitmap.x += tileWidth;
				}
				else
				{
					this.flipped = true;
					this.canvasBitmap.x -= tileWidth;
				}
			}
			return true;
		}
		
		private function onEnterframe(e:Event):void
		{
			if (endOfAnimation)
			{
				removeEventListener(Event.ENTER_FRAME, onEnterframe);
				dispatchEvent(new PFCommonSemaphoreEvent(PFCommonSemaphoreEvent.AVAILABLE));
			}
			endOfAnimation = false;
			if (animationCount == animationDelay)
			{
				animationXIndex++;
				animationCount = 0;
				if (animationXIndex == xTilesLength)
				{
					animationYIndex++;
					if (animationYIndex == yTilesLength && animationXIndex == xTilesLength)
					{
						endOfAnimation = true;
					}
					animationXIndex = 0;
				}
				if (animationYIndex == yTilesLength)
				{
					animationYIndex = 0;
				}
			}
			else
			{
				animationCount++;
			}
			if (endOfAnimation == false)
			{
				tileRect.x = animationXIndex * tileWidth;
				tileRect.y = animationYIndex * tileHeight;
				canvasBD.copyPixels(tileSheet, tileRect, tilePoint);
			}
			else
			{
				animationXIndex = 0;
				animationYIndex = 0;
				endOfAnimation = true;
			}
		}
	}
}